// ==UserScript==
// @name         lib-util.js
// @namespace    https://github.com/777555777/tampermonkey-lib
// @version      0.1.0
// @description  Provides utility functions
// @grant        unsafeWindow
// @match        *://*/*
// ==/UserScript==

/**
 * 安全地选择一个DOM元素，如果选择失败，则显示控制台错误。
 * @param {string} selector - 元素的选择。
 * @param {HTMLElement} [sourceElement=document] - 要搜索的元素。
 * @returns {HTMLElement | undefined} 选中的元素或未定义的元素，如果没有找到。
 */
function querySelectorSafe(selector, sourceElement = document) {
    const element = sourceElement.querySelector(selector)
    if (element) {
        return element
    } else {
        console.error(`Selector: ${selector} was not able to find a value!`)
        return undefined
    }
}

/**
 * 创建一个承诺，在给定的毫秒数加上随机延迟后实现。
 * @param {number} milliseconds - 至少需要等待的毫秒数。
 * @param {number} [maxRandom=0] - 额外随机延迟的上界。
 * @returns {Promise<void>} 在指定的毫秒数加上随机延迟之后实现的承诺。
 */
function sleep(milliseconds, maxRandom = 0) {
    const randomDelay = Math.floor(Math.random() * maxRandom)
    return new Promise((resolve) => setTimeout(resolve, milliseconds + randomDelay))
}

/**
 * 从给定的URL下载文件，并显示加载指示器。
 * @param {string} fileUrl - 要下载的文件的URL.
 * @param {string} fileName - 要保存文件的名称。
 */
async function downloadFileWithProgress(fileUrl, fileName) {
    const loadingIndicator = createLoadingIndicator()

    try {
        const response = await fetch(fileUrl)
        const reader = response.body.getReader()
        const contentLength = +response.headers.get("Content-Length")
        let receivedLength = 0
        const chunks = []

        while (true) {
            const { done, value } = await reader.read()
            if (done) break
            chunks.push(value)
            receivedLength += value.length

            // Fortschrittsanzeige更新
            updateLoadingIndicator(loadingIndicator, receivedLength, contentLength)
        }

        const blob = new Blob(chunks)
        const a = document.createElement("a")
        const objectUrl = URL.createObjectURL(blob)
        a.href = objectUrl
        a.download = fileName
        document.body.appendChild(a)
        a.style.display = "none"
        a.click()
        URL.revokeObjectURL(objectUrl)
        document.body.removeChild(a)
    } catch (err) {
        console.error("Error downloading the file: ", err)
    } finally {
        removeLoadingIndicator(loadingIndicator)
    }
}

unsafeWindow.querySelectorSafe = querySelectorSafe
unsafeWindow.sleep = sleep
unsafeWindow.downloadFileWithProgress = downloadFileWithProgress
